package com.jiashihui.web.controller.intensifier;

import com.jiashihui.web.config.Constant;
import com.jiashihui.web.controller.HelloController;
import com.jiashihui.web.exception.MyException;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * controller 增强器
 * @author jiashihui
 * @since 2019 ControllerAdvice 注解，可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute，并应用到所有@RequestMapping中。
 * assignableTypes  指定拦截类名称，除此之外，该注解还支持指定包扫描范围、注解范围等等。
 */
@ControllerAdvice(assignableTypes = HelloController.class)
public class MyControllerAdvice {
    /**
     * 应用到所有@RequestMapping注解方法，在其执行之前初始化数据绑定器
     * @param binder
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        Constant.code = "10002";
    }

    /**
     * 把值绑定到Model中，使全局@RequestMapping可以获取到该值
     * @param model
     */
    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("author", "Magical Sam");
    }

    /**
     * 全局异常捕捉处理
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Map errorHandler(Exception ex) {
        Map map = new HashMap();
        map.put("code", 100);
        map.put("msg", ex.getMessage());
        return map;
    }

    /**
     * 拦截捕捉自定义异常 MyException.class
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = MyException.class)
    public Map myErrorHandler(MyException ex) {
        Map map = new HashMap();
        map.put("code", ex.getCode());
        map.put("msg", ex.getMsg());
        return map;
    }

    /**
     * 如果不需要返回json数据，而要渲染某个页面模板返回给浏览器。
     * @param ex
     * @return
     */
//    @ExceptionHandler(value = MyException.class)
//    public ModelAndView myErrorHandlerView(MyException ex) {
//        ModelAndView modelAndView = new ModelAndView();
//        modelAndView.setViewName("error");
//        modelAndView.addObject("code", ex.getCode());
//        modelAndView.addObject("msg", ex.getMsg());
//        return modelAndView;
//    }

}
